/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.sorbonne.inf5.yams.model;

import fr.sorbonne.inf5.yams.model.combinaison.Combinaison;
import fr.sorbonne.inf5.yams.model.combinaison.SuperieurCombinaison;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * Cette classe modélise le score d'un joueur pour une partie de Yam'
 * @author Oukherfellah Riad
 * @author Dubos Romain
 */
public class Score {

    /**
     * Les Combinaisons sont rangées dans trois parties
     * Haute, Centrale et Basse
     */
    public static final String PARTIE_HAUTE = "PARTIE_HAUTE";
    public static final String PARTIE_CENTRALE = "PARTIE_CENTRALE";
    public static final String PARTIE_BASSE = "PARTIE_BASSE";
    private Map<Combinaison, Integer> partieHaute;
    private Map<Combinaison, Integer> partieCentrale;
    private Map<Combinaison, Integer> partieBasse;
    private Map<Combinaison, Boolean> combinaisonsValide;
    private int scoreFinal;

    /**
     * Initialise un feuille de score
     * @param partieHaute représente les combinaisons de la partie haute
     * @param partieCentrale représente les combinaisons de la partie centrale
     * @param PartieBasse représente les combinaisons de la partie basse
     */
    public Score(Set<Combinaison> partieHaute, Set<Combinaison> partieCentrale, Set<Combinaison> PartieBasse) {
        this.combinaisonsValide = new HashMap<Combinaison, Boolean>();
        this.partieHaute = new LinkedHashMap<Combinaison, Integer>();
        for (Combinaison c : partieHaute) {
            this.partieHaute.put(c, 0);
            this.combinaisonsValide.put(c, false);
        }

        this.partieCentrale = new LinkedHashMap<Combinaison, Integer>();
        for (Combinaison c : partieCentrale) {
            this.partieCentrale.put(c, 0);
            this.combinaisonsValide.put(c, false);
        }

        this.partieBasse = new LinkedHashMap<Combinaison, Integer>();
        for (Combinaison c : PartieBasse) {
            this.partieBasse.put(c, 0);
            this.combinaisonsValide.put(c, false);
        }



    }

    public Score(int score){
        this.scoreFinal = score;
    }

    /**
     * Calcule le score de la partie haute
     * @return le score de la partie haute
     */
    public int scorePartieHaute() {
        int score = 0;
        for (Combinaison c : this.partieHaute.keySet()) {
            score += this.partieHaute.get(c);
        }
        if (score >= 60) {
            int prime = score - 60;
            score += 30 + prime;
        }
        return score;
    }

    /**
     * Calcule le score de la partie centrale
     * On calcul la différence entre la première combinaison et la deuxième
     * @return le score de la partie centrale
     */
    public int scorePartieCentrale() {
        if (this.partieCentrale.values().toArray().length != 2) {
            return 0;
        }
        int superieur = 0;
        int inferieur = 0;
        superieur = (Integer) this.partieCentrale.values().toArray()[0];
        inferieur = (Integer) this.partieCentrale.values().toArray()[1];


        return superieur - inferieur;
    }

    /**
     * Calcule le score de la partie centrale
     * @return le score de la partie centrale
     */
    public int scorePartieBasse() {
        int score = 0;
        for (Combinaison c : this.partieBasse.keySet()) {
            score += this.partieBasse.get(c);
        }
        return score;
    }

    /**
     * Calcule l'addition de toutes les parties (haute, centrale, basse)
     * @return retourne le score finale
     */
    public int scoreFinal() {
        return scorePartieHaute() + scorePartieCentrale() + scorePartieBasse();
    }

    /**
     * Ajoute un score à une combinaison 
     * @param combinaison la combinaison pour laquelle on veut ajouter le score
     * @param score Le score à ajouter 
     */
    public void ajouterScore(Combinaison combinaison, int score) {

        for (Combinaison c : partieHaute.keySet()) {
            if (c.getIntitule().equals(combinaison.getIntitule())) {
                partieHaute.put(c, score);
                this.combinaisonsValide.put(c, true);
                return;
            }
        }
        for (Combinaison c : partieCentrale.keySet()) {
            if (c.getIntitule().equals(combinaison.getIntitule())) {
                partieCentrale.put(c, score);
                this.combinaisonsValide.put(c, true);
                return;
            }
        }
        for (Combinaison c : partieBasse.keySet()) {
            if (c.getIntitule().equals(combinaison.getIntitule())) {
                partieBasse.put(c, score);
                this.combinaisonsValide.put(c, true);
                return;
            }
        }

    }

    /**
     * Renvoie les combinaison avec leur score associé
     * Les combinaisons sont dans l'ordre dans lequel elles ont été ajouté
     * @return map avec combinaison et score associé
     */
    public Map<Combinaison, Integer> renvoyerScore() {
        Map<Combinaison, Integer> returnMap = new LinkedHashMap<Combinaison, Integer>();
        returnMap.putAll(this.partieHaute);
        returnMap.putAll(this.partieCentrale);
        returnMap.putAll(this.partieBasse);
        return returnMap;
    }

    /**
     * Renvoie vrai si la combinaison ne contient pas encore de score
     * @param combinaison la combinaison a rechercher
     * @return vrai si la combinaison ne contient pas encore de score false sinon
     */
    public boolean combinaisonLibre(Combinaison combinaison) {
        for (Combinaison c : combinaisonsValide.keySet()) {
            if (c.getIntitule().equals(combinaison.getIntitule())) {
                return combinaisonsValide.get(c);
            }
        }
        return true;

    }

    @Override
    public String toString() {
        String s = "\n";
        for (Combinaison c : partieHaute.keySet()) {
            s += c + " ->" + partieHaute.get(c) + "\n";
        }
        s += "Partie haute : " + scorePartieHaute() + "\n";

        for (Combinaison c : partieCentrale.keySet()) {
            s += c + " ->" + partieCentrale.get(c) + "\n";
        }
        s += "Partie centrale : " + scorePartieCentrale() + "\n";

        for (Combinaison c : partieBasse.keySet()) {
            s += c + " ->" + partieBasse.get(c) + "\n";
        }
        s += "Partie basse : " + scorePartieBasse() + "\n";
        s += "\nTOTAL = " + scoreFinal() + "\n";
        return s;
    }

    public boolean scoreComplet(){
        for(Boolean bool : combinaisonsValide.values()){
            if(!bool){
                return false;
            }
        }
        return true;
    }
}
